home *** CD-ROM | disk | FTP | other *** search
/ 9-Digit Zip Code Directory / 9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO / z4src.zip / CLLIST.CPP < prev    next >
C/C++ Source or Header  |  1993-06-11  |  21KB  |  680 lines

  1. //----------------------------------------------------------------------------
  2. //                            MODULE DESCRIPTION
  3. //
  4. //  Module:    cllist.cpp
  5. //   Title:    C++ Class Libraries
  6. //  Notice:    John M. Weeder
  7. //                 Copyright (c) 1993. All rights reserved.
  8. //             This module contains proprietary information and should be 
  9. //                treated as confidential.
  10. //
  11. //----------------------------------------------------------------------------
  12. //                           MAINTENANCE HISTORY
  13. //
  14. // $Workfile$
  15. // $Revision$
  16. //   $Author$
  17. //     $Date$
  18. //      $Log$    
  19. //
  20. //----------------------------------------------------------------------------
  21. //                             MODULE NARRATIVE
  22. //
  23. //    This module contains code for the class CL_LIST.
  24. //
  25. //    The code in this module may be written in C++ or C.
  26. //
  27. //    This module is portable to:
  28. //        DOS 3.X+
  29. //        MS Windows 3.X+
  30. //        OS/2 2.X+
  31. //        OS/2 2.0 PM
  32. //
  33. //    The following compilers are supported:
  34. //        MSC 6.0A
  35. //        MSC/C++ 7.0
  36. //        Borland C++ 3.1 for DOS
  37. //        Borland C++ 1.0 for OS/2 2.X
  38. //
  39. //----------------------------------------------------------------------------
  40. #include <class.hpp>
  41.  
  42.  
  43. //----------------------------------------------------------------------------
  44. //   Description:    Default constructor
  45. //    Parameters:    _pfnlistcomp            List compare function
  46. //       Returns:    
  47. //----------------------------------------------------------------------------
  48. FN_M CL_LIST::CL_LIST(PFNLISTCOMP _pfnlistcomp)
  49. {
  50.     CL_LIST::Initialize(CL_INIT_CLASS);
  51.     pfnlistcomp = _pfnlistcomp;
  52. }
  53.  
  54.  
  55. //----------------------------------------------------------------------------
  56. //   Description:    Copy constructor
  57. //    Parameters:    rccl_list        Reference to object to copy.
  58. //       Returns:    
  59. //----------------------------------------------------------------------------
  60. FN_M CL_LIST::CL_LIST(RCCL_LIST rccl_list)
  61. {
  62.     CL_LIST::Initialize(CL_INIT_CLASS);
  63.     *this = rccl_list;
  64. }
  65.  
  66.  
  67. //----------------------------------------------------------------------------
  68. //   Description:    Destructor
  69. //    Parameters:
  70. //       Returns:    
  71. //----------------------------------------------------------------------------
  72. FN_M CL_LIST::~CL_LIST()
  73. {
  74.     CL_LIST::Destroy(FALSE);
  75. }
  76.  
  77.  
  78. //----------------------------------------------------------------------------
  79. //   Description:    Delete an element from a list
  80. //    Parameters:    pcl_element        Element to add.
  81. //                        pelemAfter        Element to insert after.
  82. //                                            Ignored if list is sorted.
  83. //                                            If NULL, insert at start of list.
  84. //                                            Default is NULL.
  85. //       Returns:
  86. //----------------------------------------------------------------------------
  87. VOID FN_M CL_LIST::Add(PCL_ELEMENT pcl_element, PCL_ELEMENT pelemAfter)
  88. {
  89.     Assert(pcl_element && pcl_element != pelemAfter);
  90.     Assert(pelemAfter == NULL || Index(pelemAfter) >= 0);
  91.  
  92.     if (pcl_element->InList())                // Delete from current list
  93.         pcl_element->List()->Delete(pcl_element);
  94.  
  95.     if (pfnlistcomp)                            // If sorted list, search for
  96.         {                                            // place to insert element into list
  97.         pelemAfter = pelemFirst;
  98.         if (pfnlistcomp(pelemAfter, pcl_element) > 0)
  99.             pelemAfter = NULL;
  100.         if (pelemAfter)
  101.             {
  102.             while (pelemAfter->pelemNext
  103.             && (*pfnlistcomp)(pelemAfter->pelemNext, pcl_element) < 0)
  104.                 {
  105.                 pelemAfter = pelemAfter->pelemNext;
  106.                 }
  107.             }
  108.         }
  109.     if (pelemAfter == NULL || pelemFirst == NULL)
  110.         {
  111.         if (pelemFirst)                        // Link to first element
  112.             pelemFirst->pelemPrev = pcl_element;
  113.         pcl_element->pelemNext = pelemFirst;
  114.  
  115.         pelemFirst = pcl_element;            // Point to new head of list
  116.  
  117.         if (pelemLast == NULL)                // If only element, point tail to it
  118.             pelemLast = pcl_element;
  119.  
  120.         if (pelemCur == NULL)                // If no current element, set
  121.             pelemCur = First();                //  to first element
  122.         }
  123.     else                                            // Insert in the middle or end of the
  124.         {                                            //  list
  125.         pcl_element->pelemNext = pelemAfter->pelemNext;
  126.         pcl_element->pelemPrev = pelemAfter;
  127.         pelemAfter->pelemNext = pcl_element;
  128.         if (pcl_element->pelemNext)
  129.             pcl_element->pelemNext->pelemPrev = pcl_element;
  130.         else
  131.             pelemLast = pcl_element;
  132.         }
  133.     pcl_element->plist = this;
  134.     cElems++;
  135.     return ;
  136. }
  137.  
  138.  
  139. //----------------------------------------------------------------------------
  140. //   Description:    Delete an element from a list
  141. //    Parameters:    pcl_element        Element to delete
  142. //                                            If NULL, return offset of current element.
  143. //                                            Default is NULL.
  144. //       Returns:    
  145. //----------------------------------------------------------------------------
  146. VOID FN_M CL_LIST::Delete(PCL_ELEMENT pcl_element)
  147. {
  148.     if (pcl_element == NULL)
  149.         pcl_element = Current();
  150.  
  151.     if (pcl_element == NULL)
  152.         return ;
  153.  
  154.     Assert(Index(pcl_element) >= 0);
  155.  
  156.     // Remove from list
  157.     if (pcl_element->pelemNext)
  158.         pcl_element->pelemNext->pelemPrev = pcl_element->pelemPrev;
  159.  
  160.     if (pcl_element->pelemPrev)
  161.         pcl_element->pelemPrev->pelemNext = pcl_element->pelemNext;
  162.  
  163.     // Adjust list
  164.     if (pelemFirst == pcl_element)
  165.         pelemFirst = pcl_element->pelemNext;
  166.  
  167.     if (pelemLast == pcl_element)
  168.         pelemLast = pcl_element->pelemPrev;
  169.  
  170.     if (pelemCur == pcl_element)
  171.         pelemCur = NULL;
  172.  
  173.     cElems--;
  174.  
  175.     // Reset element
  176.     pcl_element->pelemPrev = pcl_element->pelemNext = NULL;
  177.     pcl_element->plist = NULL;
  178.     return;
  179. }
  180.  
  181. //----------------------------------------------------------------------------
  182. //   Description:    Destroy object. Free any resources used by object.
  183. //                          Normally called by destructor.
  184. //                        Should allow multiple calls from various classes.
  185. //    Parameters:    fDestroyAll        Destroy parents also?
  186. //                                            Default is TRUE.
  187. //       Returns:    TRUE if successful.
  188. //----------------------------------------------------------------------------
  189. BOOL FN_M CL_LIST::Destroy(BOOL fDestroyAll)
  190. {
  191.     PCL_ELEMENT pelem;
  192.     SetCurrent();
  193.     while ((pelem = Current()) != NULL)
  194.         {
  195.         Next();
  196.         Delete(pelem);
  197.         delete pelem;
  198.         }
  199.     CL_LIST::Initialize(CL_INIT_CLASS_VARS);
  200.     if (fDestroyAll)                            // Destroy parent.
  201.         CL_LIST_PARENT::Destroy(fDestroyAll);                    
  202.     return TRUE;
  203. }
  204.  
  205.  
  206. //----------------------------------------------------------------------------
  207. //   Description:    Search for a list element. A simple linear search is used.
  208. //                          Only the first element is returned.
  209. //    Parameters:    pfnlistfind        Search function.
  210. //                        pv                    Search key.
  211. //       Returns:    Pointer to element or NULL.
  212. //----------------------------------------------------------------------------
  213. PCL_ELEMENT FN_M CL_LIST::Find(PFNLISTFIND pfnlistfind, PVOID pv)
  214. {
  215.     Assert(pfnlistfind);
  216.  
  217.     PCL_ELEMENT pelem = pelemFirst;
  218.  
  219.     while (pelem && (*pfnlistfind)(pelem, pv) != 0)
  220.         pelem = pelem->pelemNext;
  221.  
  222.     return pelem;
  223. }
  224.  
  225.  
  226. //----------------------------------------------------------------------------
  227. //   Description:    Get element by index.
  228. //    Parameters:    sIndex    Index of element to return.
  229. //       Returns:    Pointer to element or NULL.
  230. //----------------------------------------------------------------------------
  231. PCL_ELEMENT FN_M CL_LIST::Get(SIZET cIndex)
  232. {
  233.     if (cIndex >= cElems)
  234.         return NULL;
  235.  
  236.     PCL_ELEMENT pelem = pelemFirst;
  237.  
  238.     for (;cIndex; cIndex--)
  239.         pelem = pelem->pelemNext;
  240.  
  241.     return pelem;
  242. }
  243.  
  244.  
  245. //----------------------------------------------------------------------------
  246. //   Description:    Return offset of element in list.
  247. //    Parameters:    pcl_element        Element to return offset of. 
  248. //                                            If NULL, return offset of current element.
  249. //                                            Default is NULL.
  250. //       Returns:    Offset from first element. 0..Count()-1
  251. //                        -1 for error or element not found.
  252. //----------------------------------------------------------------------------
  253. SHORT FN_M CL_LIST::Index(PCL_ELEMENT pcl_element)
  254. {
  255.     if (pcl_element == NULL)
  256.         pcl_element = Current();
  257.  
  258.     if (pcl_element)
  259.         {
  260.         SHORT sIndex = 0;                        // Index of element
  261.         PCL_ELEMENT pelem = pelemFirst;    // Search for element
  262.         while (pelem && pelem != pcl_element)
  263.             {
  264.             pelem = pelem->pelemNext;
  265.             sIndex++;
  266.             }
  267.         if (pelem)                                // Found it, return index
  268.             return sIndex;
  269.         }
  270.     return -1;                                    // Not found
  271. }
  272.  
  273.  
  274. //----------------------------------------------------------------------------
  275. //   Description:    Initialize object. 
  276. //                          Normally called by constructor.
  277. //                        Should allow multiple calls from various classes.
  278. //    Parameters:    sInit        Initialization code. May be one of the following:
  279. //                                        CL_INIT_CLASS            Reset class variables and
  280. //                                                                    and dynamic allocations for
  281. //                                                                    this class only.
  282. //                                        CL_INIT_CLASS_VARS    Reset class variables for
  283. //                                                                    this class only.
  284. //                                        CL_INIT_VARS            Reset class variables for
  285. //                                                                    this class only.
  286. //                                        CL_INIT_ALL                Initialize class and all 
  287. //                                                                    parent class, including
  288. //                                                                    dynamic memory allocation.
  289. //                                    Default is CL_INIT_ALL
  290. //       Returns:    TRUE if successful.
  291. //----------------------------------------------------------------------------
  292. BOOL FN_M CL_LIST::Initialize(SHORT sInit)
  293. {
  294.     if (sInit == CL_INIT_VARS || sInit == CL_INIT_ALL)
  295.         CL_LIST_PARENT::Initialize(sInit);
  296.  
  297.     pfnlistcomp = NULL;
  298.     pelemFirst = pelemLast = pelemCur = NULL;
  299.     cElems = 0;
  300.     return TRUE;
  301. }
  302.  
  303.  
  304. //----------------------------------------------------------------------------
  305. //   Description:    Increment operator
  306. //    Parameters:
  307. //       Returns:    Pointer to element or null
  308. //----------------------------------------------------------------------------
  309. PCL_ELEMENT FN_M CL_LIST::Next()
  310. {
  311.     if (pelemCur)
  312.         pelemCur = pelemCur->pelemNext;
  313.  
  314.     return pelemCur;
  315. }
  316.  
  317.  
  318. //----------------------------------------------------------------------------
  319. //   Description:    Assignment operator
  320. //                          NOTE: Don't copy object into self
  321. //    Parameters:    rccl_list        Reference to right value.
  322. //       Returns:    Reference to new object.
  323. //----------------------------------------------------------------------------
  324. RCCL_LIST FN_M CL_LIST::operator=(RCCL_LIST rccl_list)
  325. {
  326.     if (this != &rccl_list)
  327.         {
  328.         Invalid("CL_LIST::operator=");
  329.         }
  330.     return (RCCL_LIST)*this;
  331. }
  332.  
  333.  
  334. //----------------------------------------------------------------------------
  335. //   Description:    Add element to list
  336. //    Parameters:    pCL_ELEMENT            Element to add.
  337. //       Returns:    Reference to new object.
  338. //----------------------------------------------------------------------------
  339. RCL_LIST FN_M CL_LIST::operator+=(PCL_ELEMENT pcl_element)
  340. {
  341.     Add(pcl_element);
  342.     return *this;
  343. }
  344.  
  345.  
  346. //----------------------------------------------------------------------------
  347. //   Description:    Delete element from list
  348. //    Parameters:    pcl_element            Element to delete.
  349. //       Returns:    Reference to new object.
  350. //----------------------------------------------------------------------------
  351. RCL_LIST FN_M CL_LIST::operator-=(PCL_ELEMENT pcl_element)
  352. {
  353.     Assert(pcl_element);
  354.     Delete(pcl_element);
  355.     return *this;
  356. }
  357.  
  358.  
  359. //----------------------------------------------------------------------------
  360. //   Description:    Return element at a particular offset
  361. //    Parameters:
  362. //       Returns:    Pointer to element or null
  363. //----------------------------------------------------------------------------
  364. PCL_ELEMENT FN_M CL_LIST::operator[](SHORT sIndex)
  365. {
  366.     return Get(sIndex);
  367. }
  368.  
  369.  
  370. //----------------------------------------------------------------------------
  371. //   Description:    Increment operator - prefix.
  372. //    Parameters:
  373. //       Returns:    Pointer to element or null
  374. //----------------------------------------------------------------------------
  375. PCL_ELEMENT FN_M CL_LIST::operator++()
  376. {
  377.     if (pelemCur)
  378.         pelemCur = pelemCur->pelemNext;
  379.  
  380.     return pelemCur;
  381. }
  382.  
  383.  
  384. //----------------------------------------------------------------------------
  385. //   Description:    Increment operator - postfix.
  386. //    Parameters:
  387. //       Returns:    Pointer to element or null
  388. //----------------------------------------------------------------------------
  389. PCL_ELEMENT FN_M CL_LIST::operator++(int)
  390. {
  391.     if (pelemCur)
  392.         pelemCur = pelemCur->pelemNext;
  393.  
  394.     return pelemCur;
  395. }
  396.  
  397.  
  398. //----------------------------------------------------------------------------
  399. //   Description:    Decrement operator - prefix.
  400. //    Parameters:
  401. //       Returns:    Pointer to element or null
  402. //----------------------------------------------------------------------------
  403. PCL_ELEMENT FN_M CL_LIST::operator--()
  404. {
  405.     if (pelemCur)
  406.         pelemCur = pelemCur->pelemPrev;
  407.  
  408.     return pelemCur;
  409. }
  410.  
  411.  
  412. //----------------------------------------------------------------------------
  413. //   Description:    Decrement operator - postfix.
  414. //    Parameters:
  415. //       Returns:    Pointer to element or null
  416. //----------------------------------------------------------------------------
  417. PCL_ELEMENT FN_M CL_LIST::operator--(int)
  418. {
  419.     if (pelemCur)
  420.         pelemCur = pelemCur->pelemPrev;
  421.  
  422.     return pelemCur;
  423. }
  424.  
  425.  
  426. //----------------------------------------------------------------------------
  427. //   Description:    Decrement operator
  428. //    Parameters:
  429. //       Returns:    Pointer to element or null
  430. //----------------------------------------------------------------------------
  431. PCL_ELEMENT FN_M CL_LIST::Previous()
  432. {
  433.     if (pelemCur)
  434.         pelemCur = pelemCur->pelemPrev;
  435.  
  436.     return pelemCur;
  437. }
  438.  
  439.  
  440. //----------------------------------------------------------------------------
  441. //   Description:    Retrieve object from persistent storage
  442. //    Parameters:    pcsz        Name of object.
  443. //                        pcszSub    Sub-name of object.
  444. //                                    The first character of the name should be '~'.
  445. //                                    If NULL, no sub name is available.
  446. //                                    Default is NULL
  447. //       Returns:    TRUE if successful.
  448. //----------------------------------------------------------------------------
  449. BOOL FN_M CL_LIST::Retrieve(PCSZ pcsz, PCSZ pcszSub)
  450. {
  451.     Assert(pcsz);
  452.                                                     // Create sub-name for object
  453.     CL_STRING string("%s~CL_LIST", (pcszSub ? pcszSub: ""));
  454.     if (string.IsError())
  455.         return FALSE;
  456.                                                     // Get parent
  457.     if (!CL_LIST_PARENT::Retrieve(pcsz, (PCSZ)string))
  458.         return FALSE;
  459.  
  460.     return !IsError();
  461. }
  462.  
  463.  
  464. //----------------------------------------------------------------------------
  465. //   Description:    Return offset of element in list.
  466. //    Parameters:    pcl_element        Set current element.
  467. //                                            If NULL, make first element current.
  468. //                                            Default is NULL.
  469. //       Returns:    
  470. //----------------------------------------------------------------------------
  471. PCL_ELEMENT FN_M CL_LIST::SetCurrent(PCL_ELEMENT pcl_element)
  472. {
  473.     if (pcl_element == NULL)
  474.         pcl_element = First();
  475.  
  476.     Assert(pcl_element == NULL || Index(pcl_element) >= 0);
  477.  
  478.     pelemCur = pcl_element;
  479.     return pelemCur;
  480. }
  481.  
  482.  
  483. //----------------------------------------------------------------------------
  484. //   Description:    Store object to persistent storage
  485. //    Parameters:    pcsz        Name of object.
  486. //                        pcszSub    Sub-name of object.
  487. //                                    The first character of the name should be '~'.
  488. //                                    If NULL, no sub name is available.
  489. //                                    Default is NULL
  490. //       Returns:    TRUE if successful.
  491. //----------------------------------------------------------------------------
  492. BOOL FN_M CL_LIST::Store(PCSZ pcsz, PCSZ pcszSub)
  493. {
  494.     Assert(pcsz);
  495.     if (IsError())                                // Check that object is valid
  496.         return FALSE;
  497.                                                     // Create sub-name for object
  498.     CL_STRING string("%s~CL_LIST", (pcszSub ? pcszSub: ""));
  499.     if (string.IsError())
  500.         return FALSE;
  501.                                                     // Store parent
  502.     if (!CL_LIST_PARENT::Store(pcsz, (PCSZ)string))
  503.         return FALSE;
  504.  
  505.     return TRUE;                                // Done
  506. }
  507.  
  508.  
  509. //----------------------------------------------------------------------------
  510. //   Description:    Print object value to debugging output.
  511. //    Parameters:    pccl_list        Pointer to dynamic object. 
  512. //                                    If NULL, static data elements are printed.
  513. //                                    Default is NULL.
  514. //                        pcsz        Name of object.
  515. //                                    If NULL, no name is displayed.
  516. //                                    Default is NULL.
  517. //                        cLevel    Display level. 
  518. //                                    Default is zero.
  519. //       Returns:
  520. //----------------------------------------------------------------------------
  521. #if COMPILE_DEBUG
  522. VOID FN_M CL_LIST::Print(PCCL_LIST pccl_list, PCSZ pcsz, SIZET cLevel)
  523. {
  524. #if COMPILE_TEST
  525.     OutputL(cLevel, "CL_LIST%s%s", (pcsz?"::":""), (pcsz?pcsz:""));
  526.     cLevel++;
  527.     if (pccl_list)
  528.         {
  529.         Output(" <%p>\n", pccl_list);
  530.         if(!pccl_list->IsError())
  531.             {
  532.             OutputL(cLevel, "pfnlistcomp = %p\n", pccl_list->pfnlistcomp);
  533.             OutputL(cLevel, "pelemFirst  = %p\n", pccl_list->pelemFirst );
  534.             OutputL(cLevel, "pelemLast   = %p\n", pccl_list->pelemLast  );
  535.             OutputL(cLevel, "pelemCur    = %p\n", pccl_list->pelemCur   );
  536.             OutputL(cLevel, "cElems      = %u\n", pccl_list->cElems     );
  537.             }
  538.         }
  539.     else
  540.         Output(" <NULL>\n");
  541.     CL_LIST_PARENT::Print((CL_LIST_PARENT _FAR_ *)pccl_list, pcsz, cLevel);
  542.     return ;
  543. #else
  544.     NOTUSED(cLevel);
  545.     NOTUSED(pccl_list);
  546.     NOTUSED(pcsz);
  547.     return ;
  548. #endif
  549. }
  550. #endif
  551.  
  552.  
  553. //----------------------------------------------------------------------------
  554. //    Test class
  555. //----------------------------------------------------------------------------
  556. #if COMPILE_TEST
  557. CLASSDEF(CL_LISTTEST);
  558. class CLASSTYPE CL_LISTTEST : public CL_ELEMENT
  559. {
  560.     CHAR szValue[20];
  561.  
  562. public:
  563.     CL_LISTTEST(PSZ psz)
  564.         {
  565.         strcpy(szValue, psz);
  566.         }
  567.     VOID FN_M Print()
  568.         {
  569.         Output("%s\n", szValue);
  570.         }
  571.     static SHORT FN_M Comp(PCCL_ELEMENT, PCCL_ELEMENT);
  572.     static SHORT FN_M Find(PCCL_ELEMENT, PVOID);
  573. };
  574. #endif
  575.  
  576.  
  577. //----------------------------------------------------------------------------
  578. //   Description:    Test function to sort a list alphabetically.
  579. //    Parameters:    pelem1, pelem2        Elements to compare
  580. //       Returns:    < 0     Element 1 < element 2
  581. //                        == 0     Element 1 == element 2
  582. //                        > 0     Element 1 > element 2
  583. //----------------------------------------------------------------------------
  584. #if COMPILE_TEST
  585. SHORT FN_M CL_LISTTEST::Comp(PCCL_ELEMENT pelem1, PCCL_ELEMENT pelem2)
  586. {
  587.     PCL_LISTTEST plisttest1 = (PCL_LISTTEST)pelem1;
  588.     PCL_LISTTEST plisttest2 = (PCL_LISTTEST)pelem2;
  589.     return (SHORT)strcmp(plisttest1->szValue,plisttest2->szValue);
  590. }
  591. #endif
  592.  
  593.  
  594. //----------------------------------------------------------------------------
  595. //   Description:    Test function to find a member of a list.
  596. //    Parameters:    pelem            Element to compare
  597. //                        pv                Data to compare to.
  598. //       Returns:    != 0     Element is not a match
  599. //                        == 0     Element matches
  600. //----------------------------------------------------------------------------
  601. #if COMPILE_TEST
  602. SHORT FN_M CL_LISTTEST::Find(PCCL_ELEMENT pelem, PVOID pv)
  603. {
  604.     PCL_LISTTEST plisttest = (PCL_LISTTEST)pelem;
  605.     return (SHORT)strcmp(plisttest->szValue,(PCSZ)pv);
  606. }
  607. #endif
  608.  
  609.  
  610. //----------------------------------------------------------------------------
  611. //   Description:    Run standard test suite on object.
  612. //    Parameters:    sTest        Test to run.
  613. //                                    If 0, run default tests.
  614. //                                    Default is 0.
  615. //       Returns:    TRUE if successful.
  616. //----------------------------------------------------------------------------
  617. #if COMPILE_DEBUG
  618. BOOL FN_M CL_LIST::Test(SHORT sTest)
  619. {
  620. #if COMPILE_TEST
  621.     if (sTest == 1)                            // Test 1 is always a test of storage
  622.         {
  623.         CL_LIST cl_list;
  624.         cl_list.Store("CL_LIST");
  625.         cl_list.Retrieve("CL_LIST");
  626.         CL_LIST::Print(&cl_list);
  627.         }
  628.     CL_LIST list(CL_LISTTEST::Comp);
  629.  
  630.     CL_LISTTEST elem1((PSZ)"aaaaa");
  631.     CL_LISTTEST elem2((PSZ)"bbbbb");
  632.     CL_LISTTEST elem3((PSZ)"ccccc");
  633.     CL_LISTTEST elem4((PSZ)"ddddd");
  634.     PCL_LISTTEST pelem;
  635.  
  636.     list.Add(&elem4);
  637.     list.Add(&elem1);
  638.     list += &elem3;
  639.     list.Add(&elem2);
  640.     list -= &elem3;
  641.     list.Add(&elem4);                            // Add it again
  642.     list += &elem3;
  643.     Print(&list);
  644.  
  645.     pelem    = (PCL_LISTTEST)list.Find(CL_LISTTEST::Find, "ccccc");
  646.     if (pelem)
  647.         pelem->Print();
  648.     else
  649.         return FALSE;
  650.  
  651.     list.SetCurrent();
  652.     do
  653.         {
  654.         pelem    = (PCL_LISTTEST)list.Current();
  655.         if (pelem)
  656.             pelem->Print();
  657.         else
  658.             return FALSE;
  659.         }
  660.     while (list++);
  661.  
  662.     for (SHORT i = 0; i < list.Count(); ++i)
  663.         {
  664.         pelem    = (PCL_LISTTEST)list[i];
  665.         if (pelem)
  666.             pelem->Print();
  667.         else
  668.             return FALSE;
  669.         }
  670.     return TRUE;
  671. #else
  672.     NOTUSED(sTest);
  673.     return TRUE;
  674. #endif
  675. }
  676. #endif
  677. //----------------------------------------------------------------------------
  678. //------------------------------- End of File --------------------------------
  679. //----------------------------------------------------------------------------
  680.